import { Component, OnInit, OnDestroy, Inject, ViewChild, TemplateRef } from '@angular/core'
import { DOCUMENT } from '@angular/common'
import { ActivatedRoute } from '@angular/router'
import { NzMessageService, NzModalService } from 'ng-zorro-antd'
import { ACLService } from '@delon/acl'
import { PageScrollService } from 'ngx-page-scroll-core'

import { DetailBaseClass } from '@shared/classes/DetailBaseClass'
import { Terminal, ITerminalUpdateRequest, ITerminalQueryParams, ETermVendar } from '@shared/interfaces/terminal'
import { PageService } from '@shared/services/page.service'
import { IDetailHeaderTab, StatusTextMap, IOption, StatusTextMapForTerminal } from '@shared/interfaces/common'
import { TerminalService } from '../terminal.abstract.service'
import { ETabScrollStatus } from '@shared/enums'
import { DataService } from '@shared/services/data.service'
import { DetailHeaderComponent } from '@shared/components/detail-header/detail-header.component'
import { termRemarkLength } from 'app/utils/contraints'
import { Validators } from 'app/utils/validator'
import { openDownloadDialog } from 'app/utils/helpers'
import { I18NService } from '@core'
import { PublicService } from '@shared/services/public.service'

@Component({
  selector: 'app-terminal-detail',
  templateUrl: './detail.component.html',
  styles: [],
})
export class TerminalDetailComponent extends DetailBaseClass<Terminal> implements OnInit, OnDestroy {
  @ViewChild(DetailHeaderComponent) detailHeaderComponent: DetailHeaderComponent
  @ViewChild('tpControl') tpControl: TemplateRef<any>
  @ViewChild('tpTermBrand') tpTermBrand: TemplateRef<any>
  imgSrc = 'assets/images/centaur/base-info-pic/terminal.png'

  tabs: IDetailHeaderTab[] = [
    { text: this.trans('GENERAL.INFO.COLLECT_QR_CODE'), url: './qrcode' },
    { text: this.trans('GENERAL.INFO.OTHER.SYSTEM_INFO'), url: './systems' },
    { text: this.trans('GENERAL.INFO.OTHER.TRADE_INFO'), url: './transactions' },
  ]

  termBrandOptions: IOption[]

  constructor(
    private modal: NzModalService,
    private route: ActivatedRoute,
    private msg: NzMessageService,
    private terminalService: TerminalService,
    private dataService: DataService,
    private pageScrollService: PageScrollService,
    public pageService: PageService,
    public aclService: ACLService,
    private i18n: I18NService,
    private publicService: PublicService,
    @Inject(DOCUMENT) private document: any,
  ) {
    super(pageService)
  }

  ngOnInit() {
    this.getTerminal()
    this.termBrandOptions = this.genTermBrandOptions()
  }

  getTerminal(): void {
    this.loading = false

    const termCode = this.route.snapshot.params['termCode']
    const intStoreCode = this.route.snapshot.params['intStoreCode']

    this.terminalService.getOne(intStoreCode, termCode).subscribe(terminal => {
      this.setData(terminal)
      this.initial()
      this.initColumns()
      this.loading = false
    })

    this.pageService.tabScrollStatus$.subscribe(tabStatus => {
      this.pageScroll(tabStatus)
    })
  }

  genTermBrandOptions(): IOption[] {
    return this.publicService.genOptions(ETermVendar)
  }

  ngOnDestroy() {
    this.pageService.triggerBaseEdit(false)
    this.pageService.setTabScrollStatus(ETabScrollStatus.InitialLoad)
  }

  initial() {
    this.firstColumns = [
      {
        span: 6,
        index: 'common.termCode',
        label: 'GENERAL.TERMINAL.CODE',
        labelI18n: 'GENERAL.TERMINAL.CODE',
        disEditable: true,
      },
      {
        span: 12,
        index: 'common.termVendar',
        label: '终端厂商',
        labelI18n: 'BIZ.TERMINAL.FIRM',
        template: this.tpTermBrand,
      },
      {
        span:  6,
        index: 'common.status',
        label: 'GENERAL.INFO.STATUS',
        labelI18n: 'GENERAL.INFO.STATUS',
        pipe: status => this.trans(StatusTextMapForTerminal[status]),
        disEditable: true,
      },
    ]
    this.secondColumns = [
      {
        span: 20,
        index: 'common.remark',
        label: 'GENERAL.INFO.REMARK',
        labelI18n: 'GENERAL.INFO.REMARK',
        validator: {
          funcs: [Validators.maxLength(termRemarkLength)],
          errorTips: [
            this.trans('VALIDATION.MAX_LENGTH', { length: termRemarkLength }),
          ],
        },
      },
      {
        span: 4,
        label: 'GENERAL.INFO.OPERATION',
        labelI18n: 'GENERAL.INFO.OPERATION',
        template: this.tpControl,
        operate: true,
      },
    ]
  }

  setData(terminal: Terminal): void {
    this.detailData = terminal
    this.copiedDetailData = this.copyDetailData(terminal)
    this.dataService.setTerminal(terminal)
  }

  freezeDialog(): void {
    const { termCode } = this.detailData.common
    this.modal.confirm({
      nzTitle: this.trans('GENERAL.NOTIFICATION.WARNING'),
      nzContent: this.trans('GENERAL.NOTIFICATION.TERMINAL_FREEZE_CONFIRM', { termCode }),
      nzOnOk: () => this.freeze(),
    })
  }

  unfreezeDialog(): void {
    const { termCode } = this.detailData.common
    this.modal.confirm({
      nzTitle: this.trans('GENERAL.NOTIFICATION.WARNING'),
      nzContent: this.trans('GENERAL.NOTIFICATION.TERMINAL_UNFREEZE_CONFIRM', { termCode }),
      nzOnOk: () => this.unfreeze(),
    })
  }

  freeze(): void {
    const { intStoreCode, termCode } = this.detailData.common
    this.terminalService.freeze(intStoreCode, termCode).subscribe(
      values => {
        this.getTerminal()
        this.msg.success(this.trans('GENERAL.NOTIFICATION.FREEZE_SUCCESS'))
      },
      err => {
        this.msg.error(this.trans('GENERAL.NOTIFICATION.FREEZE_FAIL'))
      },
    )
  }

  unfreeze(): void {
    const { intStoreCode, termCode } = this.detailData.common
    this.terminalService.unfreeze(intStoreCode, termCode).subscribe(
      values => {
        this.getTerminal()
        this.msg.success(this.trans('GENERAL.NOTIFICATION.UNFREEZE_SUCCESS'))
      },
      err => {
        this.msg.error(this.trans('GENERAL.NOTIFICATION.UNFREEZE_FAIL'))
      },
    )
  }

  export(): void {
    const { termCode, intStoreCode } = this.detailData.common
    const params: ITerminalQueryParams = {
      page: 1,
      size: 1,
      termCode,
      intStoreCode,
    }
    this.terminalService.getTerminalReport(params).subscribe(data => {
      const { url } = data
      openDownloadDialog(url, '导出终端')
    })
  }

  saveBase(): void {
    if (!this.checkEditValidation()) {
      this.msg.error(this.trans('GENERAL.NOTIFICATION.VALIDATION_FAIL'))
      return
    }
    try {
      this.detailHeaderComponent.hideButtons()
      this.pageService.triggerBaseEdit(false)
      this.updateColumns()
      const updateData = this.generateUpdateData()
      const { intStoreCode, termCode } = this.detailData.common
      this.terminalService.update(updateData, intStoreCode, termCode).subscribe(
        terminal => {
          this.setData(terminal)
          this.initColumns()
          this.msg.success(this.trans('GENERAL.NOTIFICATION.UPDATE_SUCCESS'))
        },
        err => {
          this.msg.error(this.trans('GENERAL.NOTIFICATION.UPDATE_FAIL'))
        },
      )
    } catch (err) {
      console.error(err)
      this.msg.error(this.trans('GENERAL.NOTIFICATION.UPDATE_FAIL'), err.message)
    }
  }

  cancelBase(): void {
    this.setData(this.copiedDetailData)
    this.clearColumnsErrorTips()
    this.initColumns()
    this.pageService.triggerBaseEdit(false)
  }

  trans(key: string, params?: Object): string {
    return this.i18n.fanyi(key, params)
  }

  private generateUpdateData(): ITerminalUpdateRequest {
    const { common, qr, version } = this.detailData
    const data: ITerminalUpdateRequest = {
      version,
      common: {
        remark: common.remark,
        termVendar: common.termVendar
      },
      qr: {
        isAmountFixed: qr.isAmountFixed,
        fixedAmt: qr.fixedAmt,
      },
    }
    return data
  }

  private pageScroll(tabStatus: number): void {
    if (tabStatus === ETabScrollStatus.InitialLoad || tabStatus === ETabScrollStatus.Stop) {
      return
    }
    this.pageScrollService.scroll({
      document: this.document,
      scrollTarget: '.cil__scroll-div',
    })
  }

  private getStatusDisplayValue(): string {
    return StatusTextMap[this.detailData.common.status]
  }
}
